//
//  GCDAsyncSocketManager.m
//  GCDAsyncSocketManagerDemo
//
//  Created by 于鹏 on 2017/7/13.
//  Copyright © 2017年 于鹏. All rights reserved.
//

#import "GCDAsyncSocketManager.h"
#import "GCDAsyncSocket.h"

//局域网
//#define hostAddress @"192.168.10.10"
//公网
//#define hostAddress @"1546310we4.iok.la"
//#define tcpPort 55001
@interface GCDAsyncSocketManager ()<GCDAsyncSocketDelegate>
@property (nonatomic, strong) GCDAsyncSocket *socket;
@property (nonatomic, strong) NSTimer *beatTimer;// 心跳定时器
@property (nonatomic, strong) NSString *host; // Socket连接的host地址
@property (nonatomic, assign) uint16_t port;  // Sokcet连接的port

@property (nonatomic, strong) NSData *sendBeatData; //心跳包数据
@property (nonatomic, assign)BOOL isDisconnectByUser; //是否为主动断开连接

@end

@implementation GCDAsyncSocketManager
+ (GCDAsyncSocketManager *)shareInstance {
    static GCDAsyncSocketManager *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc]init];
    });
    return instance;
}

- (instancetype)init {
    self = [super init];
    if (!self) {
        return nil;
    }
    self.connectStatus = -1;
    self.isDisconnectByUser = NO;

    //初始化发送心跳包数据
    Byte bytes[6] = {0xAA, 0x55, 0x04, 0x80, 0x97, 0x37};
    self.sendBeatData = [NSData dataWithBytes:bytes length:sizeof(bytes)];
    
    return self;
}

#pragma mark - socket actions
- (void)changeHost:(NSString *)host port:(NSInteger)port {
    self.host = host;
    self.port = port;
}
//
//- (void)connectSocketWithDelegate:(id)delegate {
//    if (self.connectStatus != -1) {
////        XLLog(@"TCP Socket Connect: YES");
//        return;
//    }
//    
//    self.connectStatus = 0;
//    
//    self.socket = [[GCDAsyncSocket alloc]initWithDelegate:delegate delegateQueue:dispatch_get_main_queue()];
//    
//    NSError *error = nil;
//    if(![self.socket connectToHost:self.host onPort:self.port error:&error]){
//        self.connectStatus = -1;
////        XLLog(@"TCP connect error: --- %@",error);
//        
//    }
//}

- (void)connectSocket {
    if (self.connectStatus != -1) {
//        XLLog(@"TCP Socket Connect: YES");
        return;
    }
    
    self.connectStatus = 0;
    
    self.socket = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
    
    NSError *error = nil;
    if(![self.socket connectToHost:self.host onPort:self.port error:&error]){
        self.connectStatus = -1;
//     XLLog(@"TCP connect error: --- %@",error);
        
    }
}
- (void)socketDidConnectBeginSendBeat:(NSData *)beatBody {
    if (self.connectStatus != 1) {
        return;
    }
    if (!self.beatTimer) {
        self.beatTimer = [NSTimer scheduledTimerWithTimeInterval:10
                                                          target:self
                                                        selector:@selector(sendBeat:)
                                                        userInfo:beatBody
                                                         repeats:YES];
        [[NSRunLoop mainRunLoop] addTimer:self.beatTimer forMode:NSRunLoopCommonModes];
        //开启定时器
        [self.beatTimer setFireDate:[NSDate distantPast]];
    }
}

- (void)socketWriteData:(NSData *)data {
    //    XLLog(@"向TCP发送的数据:%@",data);
    [self.socket writeData:data withTimeout:-1 tag:0];
    [self socketBeginReadData];
    
}

- (void)socketBeginReadData {
    //    [self.tcpSocket readDataToData:[GCDAsyncSocket CRLFData] withTimeout:10 maxLength:0 tag:0];
    [self.socket readDataWithTimeout:-1 tag:0];
}

- (void)disconnectSocket {
    [self.socket disconnect];
    self.connectStatus = -1;
    self.isDisconnectByUser = YES;
    if (self.beatTimer.isValid) {
        [self.beatTimer invalidate];
        self.beatTimer = nil;
    }
}

#pragma mark - GCDAsyncSocketDelegate
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port {
    self.connectStatus = 1;
    self.isDisconnectByUser = NO;
//    XLLog(@"tcp连接成功:%@",host);
    
    [self socketDidConnectBeginSendBeat:self.sendBeatData];
    [self socketBeginReadData];
}
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{
    self.connectStatus = -1;
    
//    XLLog(@"tcp连接失败 %@",err);
    if (!self.isDisconnectByUser) {
        [self connectSocket];
    }
}
- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag {
    
}
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
    if ([self.tcpSocketDelegate respondsToSelector:@selector(tcpSocketReadedData:)]) {
        [self.tcpSocketDelegate tcpSocketReadedData:data];
    }
}

#pragma mark - private method
- (void)sendBeat:(NSTimer *)timer {
    //    if (self.beatCount >= kBeatLimit) {
    //        [self disconnectSocket];
    //        return;
    //    } else {
    //        self.beatCount++;
    //    }
    //    XLLog(@"timer.userInfo:%@",timer.userInfo);
    if (timer != nil) {
        [self socketWriteData:timer.userInfo];
    }
}
@end
